import 'dart:async';

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class FirebaseHelper {
  factory FirebaseHelper() {
    return _instance;
  }

  static FirebaseHelper get instance => _instance;
  static final FirebaseHelper _instance = FirebaseHelper._internal();

  FirebaseHelper._internal() {}

  StreamSubscription<String>? _onTokenRefreshStream;

  Future<void> onTokenChanged({ValueChanged<String>? onTokenRefresh}) async {
    _onTokenRefreshStream =
        FirebaseMessaging.instance.onTokenRefresh.listen((String newToken) {
      onTokenRefresh?.call(newToken);
    });
  }

  Future<void> tearDown() async {
    await _onTokenRefreshStream?.cancel();
  }

  Future<void> subscribeToTopic(String topic) async {
    await FirebaseMessaging.instance.subscribeToTopic(topic);
  }

  Future<void> unsubscribeFromTopic(String topic) async {
    await FirebaseMessaging.instance.unsubscribeFromTopic(topic);
  }

  bool get systemNoticePermission =>
      GetPlatform.isIOS ? _systemNoticePermission : true;
  bool _systemNoticePermission = false;

  Future<bool> requestNotificationPermission() async {
    if (!GetPlatform.isIOS) {
      return true;
    }
    NotificationSettings settings =
        await FirebaseMessaging.instance.requestPermission(
      alert: true,
      announcement: false,
      badge: true,
      carPlay: false,
      criticalAlert: false,
      provisional: false,
      sound: true,
    );

    if (settings.authorizationStatus == AuthorizationStatus.authorized) {
      _systemNoticePermission = true;
    } else if (settings.authorizationStatus == AuthorizationStatus.denied) {
      _systemNoticePermission = false;
    } else if (settings.authorizationStatus ==
        AuthorizationStatus.notDetermined) {
      _systemNoticePermission = false;
    } else if (settings.authorizationStatus ==
        AuthorizationStatus.provisional) {
      _systemNoticePermission = false;
    }
    return _systemNoticePermission;
  }

  Future<void> deleteToken() async {
    await FirebaseMessaging.instance.deleteToken().catchError((e) {
      return null;
    });
  }

  Future<String?> getToken() async {
    return await FirebaseMessaging.instance.getToken().catchError((e) {
      return "";
    });
  }
}
